﻿using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Wicture.DbRESTFul;
using Wicture.EPC.OnlineQueryProxy.Models;

namespace Wicture.EPC.OnlineQueryProxy.Processors
{
    public abstract class QueryProcessor : IQueryProcessor
    {
        public virtual int QueryTimeOut => 30000;

        public abstract string ProcessorName { get; }

        public virtual List<string> BrandCodes { get; } = new List<string> { };

        public abstract QueryProcessorTask Task { get; }

        public virtual bool Match(string @params)
        {
            JObject jObject = JsonConvert.DeserializeObject<JObject>(@params);
            var brandCode = jObject.Value<string>("brand");
            if (string.IsNullOrEmpty(brandCode))
            {
                return false;
            }
            return BrandCodes.Any(s => s.Equals(brandCode, StringComparison.CurrentCultureIgnoreCase));
        }

        public virtual object ProcessQueryResponse(QueryResponse response)
        {
            LoggerManager.Logger.LogInformation($"Query for {Task.ToString()}: {response.Params}.");
            return response;
        }


        public List<string> GetEpcSyncDbConns(string brandCode)
        {
            List<string> result = new List<string>();
            SyncDatabasesInfo syncDatabasesInfo = ConfigurationManager.Settings.GetConfig<SyncDatabasesInfo>("SyncDatabases");
            if (syncDatabasesInfo != null && syncDatabasesInfo.Epc != null && syncDatabasesInfo.Epc.Any())
            {
                result = GetConns(syncDatabasesInfo.Epc, brandCode);
            }

            return result;
        }

        public List<string> GetEsSyncDbConns(string brandCode)
        {
            List<string> result = new List<string>();
            SyncDatabasesInfo syncDatabasesInfo = ConfigurationManager.Settings.GetConfig<SyncDatabasesInfo>("SyncDatabases");
            if (syncDatabasesInfo != null && syncDatabasesInfo.Es != null && syncDatabasesInfo.Es.Any())
            {
                result = GetConns(syncDatabasesInfo.Es, brandCode);
            }

            return result;
        }

        List<string> GetConns(List<DatabasesInfo> routes, string brandCode)
        {
            List<string> result = new List<string>();
            if (routes != null && routes.Any())
            {
                foreach (var item in routes)
                {
                    var db = item.Databases.FirstOrDefault(e => e.Brands.Contains(brandCode, StringComparison.OrdinalIgnoreCase));
                    if (db != null)
                    {
                        string dbName = db.Name;
                        string connStr = $"server={item.Ip};port={item.Port};user={item.User};" +
                        $"password={item.Password};database={dbName};charset=utf8;convert zero datetime=True;";

                        result.Add(connStr);
                    }
                }
            }
            return result;
        }
    }
}
